package com.maxmlr.framework.context;

import com.maxmlr.framework.annotation.Controller;
import com.maxmlr.framework.annotation.Service;
import com.maxmlr.framework.beans.BeanDefinition;
import com.maxmlr.framework.context.support.BeanDefinitionReader;
import lombok.Data;

import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @ClassName AbstractApplicationContext
 * @Description TODO
 * @Author maxiao
 * @Date 2020/3/13 下午4:02
 * @Version V1.0
 */
@Data
public abstract class AbstractApplicationContext implements ApplicationContext {

    protected String[] configLocations;

    private BeanDefinitionReader reader;

    private DefaultListableBeanFactory beanFactory;

    /**
     * 开始工作
     *
     * @throws Exception
     */
    public void refresh() throws Exception {
        //1、定位
        this.reader = new BeanDefinitionReader(configLocations);
        System.out.println("1------------------------");

        //2、加载
        List<String> beanDefinitions = reader.loadBeanDefinitions();
        System.out.println("2------------------------");

        //3、注册
        beanFactory= new DefaultListableBeanFactory();
        beanFactory.setProperties(reader.getProperties());
        doRegisty(beanDefinitions);
        System.out.println("3------------------------");

        //4、依赖注入
        beanFactory.doAutowrited();
        System.out.println("4------------------------");

        //

    }



    /**
     * 注册
     *
     * @param beanDefinitions
     */
    private void doRegisty(List<String> beanDefinitions) {
        if (beanDefinitions.isEmpty()) return;

        try {
            for (String className : beanDefinitions) {
                Class<?> bean = Class.forName(className);

                if (bean.isInterface()) continue;

                if (!(bean.isAnnotationPresent(Service.class)
                        || bean.isAnnotationPresent(Controller.class))) {
                    continue;
                }

                BeanDefinition beanDefinition = reader.registerBean(className);
                if (Objects.nonNull(beanDefinition)) {
                    beanFactory.registerBeanDefinition(beanDefinition.getFactoryBeanName(), beanDefinition);
                }

                Class<?>[] interfaces = bean.getInterfaces();
                for (Class interClass : interfaces) {
                    beanFactory.registerBeanDefinition(interClass.getName(), beanDefinition);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object getBean(String beanName) {
        return this.getBeanFactory().getBean(beanName);
    }


    @Override
    public Set<String> getBeanDefinitionNames(){
        return this.getBeanFactory().getBeanDefinitionMap().keySet();
    }

}
